(function() {
    // 版本信息
    // 大版本---小的更新修复---地图更新
    var VERSION = '0.1.6';
    var APP = function() {

        this.el = {
            /* page */
            'grid': $("#grid"),
            'loading': $("#loading"),
            'levelList': $("#levelList"),
            'index': $("#index"),
            'room': $("#room"),
            'loadingBar': $("#loadingBar"),
            'levelListContainer': $("#levelList ul"),
            'containerWrap' : $("#levelList .wrap"),

            /* btn */
            "start": $("#start"),
            'goToIndex': $("#goToIndex"),
            'prev': $("#prev"),
            'next': $("#next"),

            'handler_txt' : $("#handler .txt"),
            'handler_prev' : $("#handler .icon-prev"),
            'handler_next' : $("#handler .icon-next")
        };

        this.tpl = {
            'lvItem': $("#tpl_lvItem").html()
        }
        this.data = {};

        this.loading();

        this.prefix = Util.browerKernel();
    }

    APP.prototype = {
        loading: function(callback) {
            this.el.grid.show();
            this.resize();

            // check version
            var oldVersion = localStorage.getItem('_ver');
            if (oldVersion != VERSION) {
                localStorage.clear();
                localStorage.setItem('_ver',VERSION);
            }
            var preload = new createjs.LoadQueue(true, "assets/img/");
            preload.on("progress", _.bind(this.handleProgress, this));
            preload.on("fileload", _.bind(this.handleFileLoad, this));
            preload.loadManifest(Global.imgManifest);
        },
        handleProgress: function(evt) {
            var w = (evt.progress * 100).toString().substring(0, 4) + '%';
            this.el.loadingBar.width(w);

            if (evt.progress == 1) {
                var me = this;
                setTimeout(function() {
                    me.init.call(me);
                }, 500);
            }
        },
        handleFileLoad: function(evt) {
            if (evt.item.name) {
                Global.imgSource[evt.item.name] = evt.item.src;
            }
        },

        init: function() {
            if (this.inited) return;
            $("body").attr('class','index');
            $("#win-loading").remove();
            this.inited = true;
            this.el.loading.hide();
            this.el.index.show();

            this.updateHandler();
            this.updateLevelList();

            this.initEvent();
        },

        updateLevelList: function() {
            // storaged data
            var lvData = localStorage.getItem('lvData');
            var lv = parseInt(localStorage.getItem('lv')) || 0;
            var me = this;
            if (!lvData) {
                lvData = [{
                        time: 0,
                        star: 0
                    }
                ]
            } else {
                lvData = JSON.parse(lvData);
            }

            var html = '';
            _.each(Global.lvList, function(i, d) {
                var isunLock = d <= lv;
                var l = lvData[d] || {
                    star: 0,
                    time: 0
                }
                var obj = {
                    'className': (isunLock ? 'unlock' : 'lock'),
                    'lv': d,
                    'idx': d + 1,
                    'star': (isunLock ? l.star : 0),
                    'time': (isunLock ? Util.formateTime(l.time) : '')
                }
                var t = _.template(me.tpl.lvItem, obj);
                if (d%16 < 1)  t = "<li>"+ t;
                if (d%16 == 15 ) t = t + "</li>";
                html += t;
            });
            this.el.levelListContainer.empty().html(html);
            this.el.levelListContainer.find('li').width( this.data.pageW );
            // init handler txt
            this.el.handler_txt.html( lv+1 + '/' + Global.lvList.length );

            this.el.containerWrap.data('pageIdx', Math.floor(lv/16));

            localStorage.setItem('lv', lv);
            localStorage.setItem('lvData', JSON.stringify(lvData));
        },

        updateHandler:function() {
            var width = Math.ceil(Global.lvList.length / 16) * this.data.pageW;
            this.el.levelListContainer.width(width);
            this.el.levelListContainer.find('li').width( this.data.pageW );
        },

        scroll:function() {
            var lv = parseInt(localStorage.getItem('lv')) || 0;
            var idx = this.el.containerWrap.data('pageIdx'),
                w = this.data.pageW;

            this.el.containerWrap.data('pageIdx',idx).animate({
                scrollLeft : idx*w
            },200);

            var pageMax = Math.floor(Global.lvList.length/16);

            this.el.handler_prev.toggle( !!idx );
            this.el.handler_next.toggle( idx < pageMax );
        },

        resize: function() {
            var height = window.innerHeight;
            var width = window.innerWidth;
            var scale = 1.5; // 960 / 640
            var cw, ch;

            if (width * scale > height) {
                ch = height;
                cw = height / scale;
            } else {
                cw = width;
                ch = cw * scale;
            }
            this.data.pageW = cw;
            this.data.pageH = ch;
            this.el.grid.width(cw);
            this.el.grid.height(ch);

            return {
                w: cw,
                h: ch
            }
        },

        initEvent: function() {
            var me = this;
            this.el.start.click(function() {
                me.el.index.hide();
                me.el.levelList.show();
                me.scroll.call(me);
            });

            this.el.levelList.on('click', '.lv-item', function() {
                var lv = $(this).data('lv');
                var isLock = $(this).hasClass('lock');
                if (isLock) return;
                me.gameStart.call(me, lv);
            });
            this.el.goToIndex.on('click', function() {
                me.el.levelList.hide();
                me.el.index.show();
            });

            $(window).resize(function() {
                var wh = me.resize.call(me);
                me.game && me.game.resize(wh);

                me.updateHandler.call(me);
                me.scroll.call(me);
            });
            $(window).on('orientationchange', function() {
                var wh = me.resize.call(me);
                me.game && me.game.resize(wh);
                me.updateHandler.call(me);
                me.scroll.call(me);
            });
            // page visibility
            document.addEventListener(me.prefix + 'visibilitychange', function onVisibilityChange(e) {
                var status = document[me.prefix + 'VisibilityState'];
                if (status == 'hidden' && me.game && me.game.status) {
                    me.game.pause();
                }
            });

            // swipe
            var ul = document.querySelector('#levelList ul');
            touch.on(ul , 'swipeleft', function(ev){
                var idx = parseInt(me.el.containerWrap.data('pageIdx')) + 1,
                    pageMax = Math.floor(Global.lvList.length/16);
                    idx = idx > pageMax ? pageMax : idx;
                me.el.containerWrap.data('pageIdx',idx);
                me.scroll.call(me,idx);
            });
            touch.on(ul , 'swiperight', function(ev){
                var idx = parseInt(me.el.containerWrap.data('pageIdx')) - 1;
                    idx = idx < 0 ? 0 : idx;
                me.el.containerWrap.data('pageIdx',idx)
                me.scroll.call(me,idx);
            });

        },

        gameStart: function(lv) {
            var opt = {
                'level': lv,
                'pageH': this.data.pageH,
                'pageW': this.data.pageW
            }
            if (this.game) {
                this.game.data.level = lv;
            } else {
                this.game = new Game(opt, this);
            }

            this.game.start();
        },

        resetGame: function() {
            this.updateLevelList();
            this.el.room.hide();
            this.el.levelList.show();
            this.scroll();
            $("body").attr('class','lvList');
        }

    }

    window.app = new APP();

})();
